/*
 * comlan
 */

package com.promfy.bughunter.domain;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.media.AudioManager;
import android.media.SoundPool;
import android.util.Log;

import com.promfy.bughunter.R;

public class CommonBug implements Bug {
	private static final String TAG = "CommonBug";
	private static final int RANDOM_SEED_MOVEMENT_FIX_SMALL = 5;
	private static final int RANDOM_SEED_MOVEMENT_FIX_BIG = 10;
	private static final int RANDOM_SEED_MOVEMENT_FIX_BIG_PLUS = 15;
	private static final int RANDOM_SEED_MOVEMENT_SMALL = 7;
	private static final int RANDOM_SEED_MOVEMENT_BIG = 20;
	protected final static int WHOLE_MOVEMENT_ICON_NUMBER = 4;
	protected static final int WHOLE_KILL_ICON_NUMBER = 2; 
	private static final int SCORE_VALUE = 2; 
	protected static Bitmap[] icons = new Bitmap[WHOLE_MOVEMENT_ICON_NUMBER];
	protected static Bitmap[] iconKill = new Bitmap[WHOLE_KILL_ICON_NUMBER];
	private PointF point = new PointF();
	private PointF curPoint = new PointF();
	private Canvas canvas;
	private Context context;
	private Paint paint;
	private int index=0;
	private Random r;
	private int screenW;
	private int screenH;
	
	private boolean inScreen = true;
	private boolean pressed = false;
	private boolean killed = false;
	private int killIndex = 0;
	private int rotateDegree;
	private PointF increP;
	private Bitmap b;
	


	public static Bitmap[] getIcons() {
		return icons;
	}
	public static void setIcons(Bitmap[] icons) {
		CommonBug.icons = icons;
	}
	public void setPressed(boolean pressed) {
		this.pressed = pressed;
		//can't move any more,(just don't set random increment)
		//show pressed animate effect
		
	}
	public boolean isPressed() {
		return pressed;
	}
	public PointF getCurPoint() {
		return curPoint;
	}

	public boolean isKilled() {
		return killed;
	}
	public void setKilled(boolean killed) {
		this.killed = killed;
	}
	public void setCurPoint(PointF curPoint) {
		this.curPoint = curPoint;
	}

	public static int getScoreValue() {
		return SCORE_VALUE;
	}
	public boolean isInScreen() {
		return inScreen;
	}

	public void setInScreen(boolean inScreen) {
		this.inScreen = inScreen;
	}

	public CommonBug(Context context, Canvas canvas, int screenW, int screenH) {
		this.canvas = canvas;
		this.context = context;
		this.screenW = screenW;
		this.screenH = screenH;
		
		paint = new Paint(); 
		paint.setColor(Color.RED);
		paint.setAntiAlias(true);
/*		//parse icons
		if(icons[0]==null)
		icons[0] = BitmapFactory.decodeResource(context.getResources(), R.drawable.bug_piaochong_1);
		if(icons[1]==null)
		icons[1] = BitmapFactory.decodeResource(context.getResources(), R.drawable.bug_piaochong_2);
		if(icons[2]==null)
		icons[2] = BitmapFactory.decodeResource(context.getResources(), R.drawable.bug_piaochong_1);
		if(icons[3]==null)
		icons[3] = BitmapFactory.decodeResource(context.getResources(), R.drawable.bug_piaochong_2);
//		if(icons[4]==null)
//		icons[4] = BitmapFactory.decodeResource(context.getResources(), R.drawable.bug_piaochong_1);
		if(iconKill[0]==null)
			iconKill[0] = BitmapFactory.decodeResource(context.getResources(), R.drawable.bug_piaochong_killed_1);
		if(iconKill[1]==null)
			iconKill[1] = BitmapFactory.decodeResource(context.getResources(), R.drawable.bug_piaochong_killed_1);*/
//		initSound();
	}
	
	/**
	 * set start-point, start-icon, 
	 * @param point 
	 */
	@Override
	public void born(PointF point) {
		this.point = point;
		this.curPoint.x = point.x;
		this.curPoint.y = point.y;
//		Log.d(TAG, "CommanBug born x = " + point.x + "  y = " + point.y);
//		Bitmap b = icons[0];
//		Matrix m = new Matrix();
//		m.setRotate(getRotateDegree());
//		b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
//		canvas.drawBitmap(b, point.x, point.y, null);
	}

	@Override
	public void cancel() {
		setInScreen(false);
	}



	/**
	 * set inreament of running which decide direction.
	 * set icon change of running which decide effect.
	 * @param canvas 
	 */
	@Override
	public void run( ) {
		curPoint = getCurPoint(point,curPoint);

		if(isKilled()) { 
			// show cancel animate effect
			b = getCurKillIcon(iconKill);
			Matrix m = new Matrix();
			m.setRotate(getRotateDegree());
			b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
			paint.setColor(Color.WHITE);
			paint.setAlpha(50);
			canvas.drawBitmap(b, curPoint.x - b.getWidth()/2, curPoint.y-b.getHeight()/2, paint);
			// add score
			paint.setTextSize(25);
			canvas.drawText("+2", curPoint.x, curPoint.y-b.getHeight(), paint);
			if(killIndex++ > 50){
				setInScreen(false);
			}
		}
		else 
		if(isPressed()){
			// show cancel animate effect
			b = getCurKillIcon(iconKill);
			Matrix m = new Matrix();
			m.setRotate(getRotateDegree());
			b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
			canvas.drawBitmap(b, curPoint.x - b.getWidth()/2, curPoint.y-b.getHeight()/2, paint);
		}
		else{
			b = getCurIcon(icons);
			Matrix m = new Matrix();
			m.setRotate(getRotateDegree());
			b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
			canvas.drawBitmap(b, curPoint.x - b.getWidth()/2, curPoint.y-b.getHeight()/2, paint);
			canvas.drawText("bbb", 50, 150, paint);
		}
		if(curPoint.x >screenW || curPoint.x < 0 || curPoint.y > screenH || curPoint.y < 0){
			setInScreen(false);
		}
	}

	private Bitmap getCurIcon(Bitmap[] icons2) {
		if(index++ >= 1000){
			index = 0;
		}
		return icons2[index%icons2.length];
	}
	
	private Bitmap getCurKillIcon(Bitmap[] icons2) {
		if(index++ >= 1000){
			index = 0;
		}
		return icons2[index%icons2.length];
	}

	
	protected PointF getRandomIncrement(PointF point){
		Random r = new Random();
		PointF increP = new PointF();
		if(index < 10){
			if(point.x == 0){
				increP.x += r.nextInt(RANDOM_SEED_MOVEMENT_SMALL);
				increP.y += r.nextInt(RANDOM_SEED_MOVEMENT_FIX_BIG_PLUS)-RANDOM_SEED_MOVEMENT_FIX_BIG_PLUS;
			}else if(point.x == screenW){
				increP.x += -(r.nextInt(RANDOM_SEED_MOVEMENT_SMALL));
				increP.y += -(r.nextInt(RANDOM_SEED_MOVEMENT_FIX_BIG_PLUS)-RANDOM_SEED_MOVEMENT_FIX_BIG_PLUS);
			}else if (point.y == 0){
				increP.x += r.nextInt(RANDOM_SEED_MOVEMENT_FIX_BIG_PLUS)-RANDOM_SEED_MOVEMENT_FIX_BIG_PLUS;
				increP.y += r.nextInt(RANDOM_SEED_MOVEMENT_SMALL);			
			}else if (point.y == screenH){
				increP.x += -(r.nextInt(RANDOM_SEED_MOVEMENT_FIX_BIG_PLUS)-RANDOM_SEED_MOVEMENT_FIX_BIG_PLUS);
				increP.y += -(r.nextInt(RANDOM_SEED_MOVEMENT_SMALL));
			}
		}else{
			if(point.x == 0){
				increP.x += r.nextInt(RANDOM_SEED_MOVEMENT_BIG)-RANDOM_SEED_MOVEMENT_FIX_SMALL;
				increP.y += r.nextInt(RANDOM_SEED_MOVEMENT_BIG)-RANDOM_SEED_MOVEMENT_FIX_BIG;
			}else if(point.x == screenW){
				increP.x += -(r.nextInt(RANDOM_SEED_MOVEMENT_BIG)-RANDOM_SEED_MOVEMENT_FIX_SMALL);
				increP.y += -(r.nextInt(RANDOM_SEED_MOVEMENT_BIG)-RANDOM_SEED_MOVEMENT_FIX_BIG);
			}else if (point.y == 0){
				increP.x += r.nextInt(RANDOM_SEED_MOVEMENT_BIG)-RANDOM_SEED_MOVEMENT_FIX_BIG;
				increP.y += r.nextInt(RANDOM_SEED_MOVEMENT_BIG)-RANDOM_SEED_MOVEMENT_FIX_SMALL;			
			}else if (point.y == screenH){
				increP.x += -(r.nextInt(RANDOM_SEED_MOVEMENT_BIG)-RANDOM_SEED_MOVEMENT_FIX_BIG);
				increP.y += -(r.nextInt(RANDOM_SEED_MOVEMENT_BIG)-RANDOM_SEED_MOVEMENT_FIX_SMALL);
			}
		}
//		LogUtils.LogD(TAG, "inreP x = "+increP.x + "     incrP y = " + increP.y);
		return increP;
	}
	
	public PointF getCurPoint(PointF point, PointF curPoint){
		if(pressed) return curPoint;
		if(index % 5 == 0){			
			increP = getRandomIncrement(point);
		}
		setRotateDegree(increP);
		curPoint.x += increP.x;
		curPoint.y += increP.y;
//		LogUtils.LogD(TAG, "curPoint x = "+curPoint.x + "     curPoint y = " + curPoint.y);
//		LogUtils.LogD(TAG, "point x = "+point.x + "     point y = " + point.y);
		return curPoint;
	}
	
	private void setRotateDegree(PointF increP) {
		float x = increP.x;
		float y = increP.y;
		if(x==0 && y==0){
			rotateDegree = 0;
		}else if (x > 0 && y == 0){
			rotateDegree = 90;
		}else if (x < 0 && y == 0){
			rotateDegree = -90;
		}else if (y < 0 && x == 0){
			rotateDegree = 0;
		}else if(y > 0 && x == 0){
			rotateDegree = 180;
		}else if (x > 0 && y < 0){
			rotateDegree = (int)(180/Math.PI * Math.atan(-x/y));
		}else if( x > 0 && y > 0){
			rotateDegree = 180 - (int)(180/Math.PI * Math.atan(x/y));
		}else if( x < 0 && y > 0){
			rotateDegree = (int) (180 + 180/Math.PI * Math.atan(-x/y));
		}else if ( x < 0 && y < 0){
			rotateDegree = 360 - (int)(180/Math.PI * Math.atan(x/y));
		}
//		LogUtils.LogD(TAG, "rotateDegree x = "+rotateDegree);

	} 
	
	public int getRotateDegree(){
		return rotateDegree;
	}
	
}
